package com.mrobuy.jdvc.service.impl;

import com.gavel.database.SQLExecutor;
import com.gavel.utils.StringUtils;
import com.jd.open.api.sdk.request.supplier.VcLibraryGetUploadTokenRequest;
import com.jd.open.api.sdk.response.supplier.VcLibraryGetUploadTokenResponse;
import com.mrobuy.jd.JdClientFactory;
import com.mrobuy.jdvc.dao.VCPictureDao;
import com.mrobuy.jdvc.entity.VCPicture;
import com.mrobuy.jdvc.service.VCPictureService;
import com.mrobuy.util.HttpUtils;
import com.mrobuy.util.IdentifierGen;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;

@Service("vcPictureService")
public class VCPictureServiceImpl implements VCPictureService {

    private static Logger LOG = LoggerFactory.getLogger(VCPictureService.class);

    @Autowired
    private VCPictureDao vcPictureDao;

    //注入
    @Autowired
    private RestTemplate restTemplate;


    private static long TIMESTAMP = 0;

    //  token 有效期: 8分钟
    private static long EXPRIE = 8*60*1000;

    private static String UPLOAD_URL = "";


    @Override
    public String loadVCPicUrl(String url, String maskId) {

        if (StringUtils.isBlank(url)) {
            return null;
        }

        VCPicture vcPicture = vcPictureDao.load(url, maskId);
        if ( vcPicture!=null  &&  StringUtils.isNotBlank(vcPicture.getVcpic())) {
            return vcPicture.getVcpic();
        }

        return uploadPic(url, maskId);
    }

    @Override
    public String loadProductVCPicUrl(String url, String maskId) {

        if (StringUtils.isBlank(url)) {
            return null;
        }

        VCPicture vcPicture = vcPictureDao.load(url, maskId);
        if ( vcPicture!=null  &&  StringUtils.isNotBlank(vcPicture.getVcpic())) {
            return vcPicture.getVcpic();
        }

        return uploadProductPic(url, maskId);
    }

    private String uploadProductPic(String url, String maskId) {
        if ( StringUtils.isBlank(url) ) {
            return null;
        }

        String localFilePath = localFilePath(url, false);
        if (StringUtils.isBlank(localFilePath)) {
            return null;
        }

        try {
            String vcUrl =  transferFile(localFilePath);

            VCPicture vcPicture = new VCPicture();
            vcPicture.setId(IdentifierGen.uuid());
            vcPicture.setUrl(url);
            vcPicture.setMaskid(maskId);
            vcPicture.setVcpic(vcUrl);

            try {
                vcPictureDao.insert(vcPicture);
            } catch (Exception e) {
                LOG.error("图片上传异常: " + e.getMessage());
            }

            return vcUrl;
        } catch (Exception e) {
            LOG.error("图片上传异常: " + e.getMessage());
            return null;
        }
    }

    /**
     * 处理图片并上传到VC
     * @param url 图片URL
     * @param maskId 品牌水印id
     * @return
     */
    private String uploadPic(String url, String maskId) {

        if ( StringUtils.isBlank(url) ) {
            return null;
        }

        String localFilePath = localFilePath(url, true);
        if (StringUtils.isBlank(localFilePath)) {
            return null;
        }

        try {
            String vcUrl =  transferFile(localFilePath);


            VCPicture vcPicture = vcPictureDao.load(url, maskId);
            if ( vcPicture==null ) {
                vcPicture = new VCPicture();
                vcPicture.setId(IdentifierGen.uuid());
                vcPicture.setUrl(url);
                vcPicture.setMaskid(maskId);
                vcPicture.setVcpic(vcUrl);
                try {
                    vcPictureDao.insert(vcPicture);
                } catch (Exception e) {
                    LOG.error("图片上传异常: " + e.getMessage());
                }
            } else {
                vcPicture.setVcpic(vcUrl);
                try {
                    vcPictureDao.update(vcPicture);
                } catch (Exception e) {
                    LOG.error("图片上传异常: " + e.getMessage());
                }
            }

            return vcUrl;
        } catch (Exception e) {
            LOG.error("图片上传异常: " + e.getMessage());
            return null;
        }
    }

    /**
     *  本地文件传到服务器
     * @param localFilePath
     * @return
     */
    private String transferFile(String localFilePath) throws Exception {


        RestTemplate restTemplate = new RestTemplate();

        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("multipart/form-data");
        headers.setContentType(type);

        //设置请求体，注意是LinkedMultiValueMap
        FileSystemResource fileSystemResource = new FileSystemResource(localFilePath);
        MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
        form.add("file", fileSystemResource);

        //用HttpEntity封装整个请求报文
        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);

        UploadRes res = restTemplate.postForObject(getUploadURL(), files, UploadRes.class);

        if ( res==null ) {
            return null;
        }
        
        return res.msg;
    }

    /**
     * 获取上传URL
     * @return
     */
    private String getUploadURL() throws Exception {
//        if ( TIMESTAMP - System.currentTimeMillis() < EXPRIE ) {
//            if ( StringUtils.isNotBlank(UPLOAD_URL) ) {
//                return UPLOAD_URL;
//            }
//        }

        UPLOAD_URL = "";

        VcLibraryGetUploadTokenRequest request=new VcLibraryGetUploadTokenRequest();
        VcLibraryGetUploadTokenResponse response = JdClientFactory.jdClient().execute(request);

        if ( response!=null && response.getUpdateToken()!=null ) {
            TIMESTAMP = System.currentTimeMillis();
            UPLOAD_URL = response.getUpdateToken().getUploadUrl();
        }

        return UPLOAD_URL;
    }

    /**
     * 图片的本地文件路径
     * @param url
     * @return
     */
    private String localFilePath(String url, boolean downloadFileNoExist) {

        // https://static.mymro.cn/pis/%E6%81%92%E8%BE%89/pu%20coated/229136.jpg
        if ( StringUtils.isBlank(url) ) {
            return null;
        }

        String localFile = url;
        if ( url.startsWith("https://static.mymro.cn/") ) {
            localFile = url.replace("https://static.mymro.cn/", "./images/");
        }

        if ( url.startsWith("https://static.grainger.cn/") ) {
            localFile = url.replace("https://static.grainger.cn/", "./images/");
        }


        File picFile = new File(localFile);
        if ( picFile.exists() ) {
            return picFile.getAbsolutePath();
        }

        if ( downloadFileNoExist ) {
            int tryCnt = 0;
            while ( true ) {
                try {
                    HttpUtils.download(url, picFile.getAbsolutePath());
                    return picFile.getAbsolutePath();
                } catch (IOException e) {
                    tryCnt++;
                    if ( tryCnt >= 3 ) {
                        LOG.error("[URL: " + url + "]图片下载失败: " + e.getMessage());
                        break;
                    }
                    LOG.warn("[URL: " + url + "]第 " + tryCnt + " 次尝试下载");
                }
            }
        }

        return null;
    }


    static class UploadRes {

        /**
         * success : true
         * code : null
         * msg : http://img20.360buyimg.com/vc/jfs/t1/149232/11/12554/52659/5f9d81c3E259f5313/2cc516f994b9c9b0.jpg
         */

        private boolean success;
        private String code;
        private String msg;

        public boolean isSuccess() {
            return success;
        }

        public void setSuccess(boolean success) {
            this.success = success;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }
    }

}
